/**
 * 第四课 类
 */
// 我们一般定义类使用关键字class 类名首字母需大写
class Test {
    // 定义属性或方法 默认可访问性为public，同时还可以是private(私有)，protected(受保护的)
    // public 类的实例可访问到，
    // private 只对当前类可访问 私有属性一般以下划线开头
    // protected 当前类及继承关系可访问到
    name: string;//默认public
    private age: number;
    protected habbies: string;
    private _sex: number;
    readonly CLASSES: number = 2 //只读属性一般全大写，es2015中的const一样，下文中不可修改
    // 构造函数，若不提供，系统也会提供一个可执行的构造函数，在实例化时执行
    constructor(name: string) {
        this.name = name;
    }
    // 获取name值
    getName() {
        return this.name;
    }
    // 设置值
    setName(name: string) {
        this.name = name;
    }
    getHabbies() {
        return this.habbies;
    }
    setHabbies(habbies: string) {
        this.habbies = habbies;
    }
    getAge() {
        return this.age;
    }
    setAge(age: number) {
        this.age = age;
    }
    // 设置sex值，若不提供set方法，则在当前类中sex属性相当于readonly只读属性
    set sex(sex: number) {
        this._sex = sex;
    }
    // 获取sex值
    get sex() {
        return this._sex;
    }
}
// let t = new Test('zhangsan');
// console.log(t.name); // 'zhangsan'
// // 在这里我们可以直接通过这种方式直接修改实例类中的属性值，虽然大部分时候不应该这样做，但是这样做并不会报错，故而有private及protected来控制属性的可访问性
// t.name = 'lishi';
// console.log(t.name);// 'lisi'
// // 受保护的，不能通过实例方式直接调用属性
// // console.log(t.habbies);
// // 对habbies设置值
// t.setHabbies('sing,switing');
// console.log(t.getHabbies());
// // age属性可访问性为private私有属性，只能在当前类中访问
// // console.log(t.age);
// // 对age设值
// t.setAge(12);
// console.log(t.getAge());
// // 设置sex
// t.sex = 0;
// console.log(t.sex);
// // 将提示没有权限修改当前属性
// // t.CLASSES = 3;
// console.log(t.CLASSES);
/**
 * 面向对象
 */
class Animal1 {
    constructor(protected name: string) {
        this.name = name;
    }
    move(leg: number = 0) {
        console.log(`my name is ${this.name} I have ${leg} legs`);
    }
}
// 类的继承
class Cat extends Animal1 {
    age: number = 0;
    constructor(name: string) {
        super(name);
        // 当存在继承关系时，基类中存在constructor，继承类中若提供constructor，则务必执行super()执行父类中的constructor
        this.age = 1;
    }
    // 重写父类中的move方法，通过super关键字调用父类的方法或属性
    move(leg = 4) {
        console.log('cat move');
        super.move(leg);
    }
}
let cat = new Cat('cat');
// cat.move()
// cat move
// my name is cat I have 4 legs
// 静态
class StaticA {
    static obj: any = { name: 'zhangsan', age: 22 }
    getName() {
        console.log(StaticA.obj.name);
    }
}
let sa = new StaticA;
// sa.getName() //zhangsan
// 抽象
abstract class AbstractA {
    abstract getName(): string;
    age: number;
    getAge(): number {
        return this.age;
    }

}
class Wolf extends AbstractA {
    name: string;
    age: number = 3;
    constructor(name: string) {
        super();
        this.name = name;
    }
    getName(): string {
        return this.name;
    }
    getHabby() {
        return 'habbies';
    }
}
let w: AbstractA = new Wolf('wolf');
// console.log(w.getName(), w.getAge()); //wolf 3
// 错误，在定义w时指定类型为抽象类，在该抽象类中不存在getHabby属性或方法
// console.log(w.getHabby());

// 构造函数
class TestName {
    constructor(private name: string) {
        this.name = name;
    }
    getName() {
        return this.name;
    }
}
let tname = new TestName('张三');
console.log(tname.getName()); //张三










